﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Trinity.Utilities;

namespace SequenceAssembler
{
	class ReadFile {
		public string Filename;
		public int InsertLength;
		public float InsertVariance;
	}

    class DeBruijnGraphBuilder
    {
		DeBruijnGraph m_graph; //< debuijn graph
        bool m_inward = true; //< if the reads are paired inward
        int m_batchReadNumber = 1024 * 1024;

		public DeBruijnGraphBuilder(BackGraph backGraph, int abundanceThreshold, short multiplicityThreshold) {
			m_graph = new DeBruijnGraph(backGraph);
			m_graph.AbundanceThreshold = abundanceThreshold;
			m_graph.MultiplicityThreshold = multiplicityThreshold;
		}

		public void Build(ReadFile[] readFiles)
		{
            DateTime start = DateTime.Now;
			using (Reader reader = new Reader(0))
			{
				foreach (var readFile in readFiles)
				{
					Console.WriteLine("Processing '{0}' ......", readFile.Filename);
					reader.Open(readFile.Filename);
					feedReads(reader, readFile.InsertLength, readFile.InsertVariance);
					Console.WriteLine("Processing '{0}' Completed.", readFile.Filename);
				}
			}
            Console.WriteLine("build graph time is " + DateTime.Now.Subtract(start).TotalSeconds);
			Console.WriteLine("Pre prune cell count: {0}", m_graph.bg.CellCount);
			m_graph.PruneLowAbundance();			
			Console.WriteLine("Post prune cell count: {0}", m_graph.bg.CellCount);
			Console.WriteLine("Connecting k-mers ......");
			m_graph.ConnectTrusted();
			Console.WriteLine("Merging coverage ......");
			m_graph.MergeCoverage();
			Console.WriteLine("De-Bruijn Graph construction completed!");
		}

        public void CalculateReadID2KmerIDIndex(Reader reader)
        {
            string[] batchReads = new string[m_batchReadNumber];
            int index = 0;
            while (reader.Next())
            {
                if (index < m_batchReadNumber)
                {
                    batchReads[index] = reader.CurrentRead.ToString();
                    index += 1;
                }
                else
                {

                }
            }
        }

		private int feedReads(Reader reader, int insLen = 100, double insVar = 25.0)
		{
            try
            {
                m_graph.AddCategory(reader.CurrentID + 1, insLen, insVar);
                while (reader.Next())
                {
                    m_graph.InsertKmers(reader.CurrentRead, reader.CurrentID);
                    if (reader.CurrentID % 10000 == 0)
                    {
                        Console.WriteLine("Processed {0} reads", reader.CurrentID);
                    }
                }
                m_graph.InsertRemainKmers();
            }
            catch (Exception e)
            {
                Log.WriteLine(e.Message);
                Log.WriteLine(e.StackTrace);
                Log.WriteLine("current read id = " + reader.CurrentID);
                Environment.Exit(0);
            }
			return 0;
		}

		public static void unitTest()
		{

		}
    }
}
